/*
 * $Id: inet.h,v 1.18 2005-12-13 08:53:41 bacon Exp $
 */

#ifndef _XP_NET_INET_H_
#define _XP_NET_INET_H_

#include <xp/types.h>
#include <xp/macros.h>
#include <xp/bas/endian.h>

/* 
 * MACRO: XP_INET4_CLASS_A
 *   Tests if an internet address belongs to class A (0-127)
 */
#define XP_INET4_CLASS_A(x) \
	((xp_ntoh32(x) & (xp_uint32_t)0x80000000) == (xp_uint32_t)0x00000000)

/* 
 * MACRO: XP_INET4_CLASS_B
 *   Tests if an internet address belongs to class B (128-191)
 */
#define XP_INET4_CLASS_B(x) \
	((xp_ntoh32(x) & (xp_uint32_t)0xC0000000) == (xp_uint32_t)0x80000000)

/* 
 * MACRO: XP_INET4_CLASS_C
 *   Tests if an internet address belongs to class C (192-223)
 */
#define XP_INET4_CLASS_C(x) \
	((xp_ntoh32(x) & (xp_uint32_t)0xE0000000) == (xp_uint32_t)0xC0000000)

typedef xp_uint16_t xp_port_t;
typedef struct xp_ip_t xp_ip_t;

// TODO: please complete this structure and related functions.
struct xp_ip_t
{
	int type;

	union  
	{
		xp_uint32_t ip4;
		xp_byte_t   ip6[16];
	} v;
};

#ifdef __cplusplus
extern "C" {
#endif

extern xp_byte_t xp_inet4_any[4];
extern xp_byte_t xp_inet4_loopback[4];

extern xp_byte_t xp_inet6_any[16];
extern xp_byte_t xp_inet6_loopback[16];

/*
 * FUNCTION: xp_inet4_strtoip
 *   Converts an internet address string to a binary address
 * 
 * PARAMETERS:
 *   str - [in] a null-terminated internet address in the standard notation
 *   ip - [out] a 32-bit IPv4 address
 *
 * RETURNS:
 *   0 on success, -1 on failure
 *
 * SEE ALSO:
 *   <xp_inet4_strxtoip> <xp_inet4_iptostrx>
 */
int xp_inet4_strtoip (const xp_char_t* str, xp_uint32_t* ip);

/*
 * FUNCTION: xp_inet4_strxtoip
 *   Converts a length-bounded internet address string to a binary address
 *
 * PARAMETERS:
 *   str - [in] a length-bounded internet address in the standard notation
 *   len - [in] the number of characters in the memory area pointed to by *str*
 *   ip - [out] a 32-bit IPv4 address
 *
 * RETURNS:
 *   0 on success, -1 on failure
 *
 * SEE ALSO:
 *   <xp_inet4_strtoip> <xp_inet4_iptostrx>
 */
int xp_inet4_strxtoip (const xp_char_t* str, xp_size_t len, xp_uint32_t* ip);

/*
 * FUNCTION: xp_inet4_iptostrx
 *   Converts an internet address to a string
 *
 * PARAMETERS:
 *   ip - [in] a 32-bit IPv4 address
 *   buf - [out] the buffer to hold a converted internet address string
 *   size - [in] the size of *buf*
 * 
 * RETURNS:
 *   The number characters in the buffer
 *
 * SEE ALSO:
 *   <xp_inet4_strtoip> <xp_inet4_strxtoip>
 */
xp_size_t xp_inet4_iptostrx (xp_uint32_t ip, xp_char_t* buf, xp_size_t size);

/*
 * FUNCTION: xp_inet4_pxtonm
 *   Converts a prefix length to a netmask
 */
int xp_inet4_pxtonm (int prefix, xp_uint32_t* netmask);

/*
 * FUNCTION: xp_inet4_nmtopx
 *   Converts a netmask to a prefix length
 */
int xp_inet4_nmtopx (xp_uint32_t netmask, int* prefix);

/*
 * FUNCTION: xp_inet4_strtoipnm
 *   Converts an ip/netmask string to numeric values
 *
 * PARAMETERS:
 *   str - [in] a string in an ip/netmask or an ip/prefix notation
 *   ip - [out] an ip address in the network byte order
 *   mask - [out] a netmask in the network byte order
 *
 * RETURNS:
 *   0 on success, -1 on failure
 * 
 * SEE ALSO:
 *   <xp_inet4_strxtoipnm>
 */
int xp_inet4_strtoipnm (
	const xp_char_t* str, xp_uint32_t* ip, xp_uint32_t* mask);

/*
 * FUNCTION: xp_inet4_strxtoipnm
 *   Converts an ip/netmask string to numeric values
 *
 * PARAMETERS:
 *   str - [in] a string in an ip/netmask or an ip/prefix notation
 *   len - [in] the length of *str*
 *   ip - [out] a pointer to memory area to hold an ip address 
 *   mask - [out] a poitner to memory area to hold a netmask
 *
 * RETURNS:
 *   0 on success, -1 on failure
 *
 * SEE ALSO:
 *   <xp_inet4_strtoipnm>
 */
int xp_inet4_strxtoipnm (
	const xp_char_t* str, xp_size_t len, xp_uint32_t* ip, xp_uint32_t* mask);

/*
 * FUNCTION: xp_inet4_ipnmtostrx
 *   Converts an internet address and a netmask to a string
 *
 * PARAMETERS:
 *   ip - [out] an ip address in the network byte order
 *   mask - [out] a netmask in the network byte order
 *   buf - [out] pointer to a buffer to hold result
 *   size - [in] buffer size
 *
 * DESCRIPTION:
 *   When the ip address and the netmask are converted to a string, 
 *   the internet address part of the string is followed by a slash and
 *   the netmask in the format of xxx.xxx.xxx.xxx.
 *
 * RETURNS:
 *   Length of the resulting string
 *
 * SEE ALSO:
 *   <xp_inet4_ipnmtostrpx>
 */
xp_size_t xp_inet4_ipnmtostrx (
	xp_uint32_t ip, xp_uint32_t mask, xp_char_t* buf, xp_size_t size);

/*
 * FUNCTION: xp_inet4_ipnmtostrpx
 *   Converts an internet address and a netmask to a string
 *
 * PARAMETERS:
 *   ip - [out] an ip address in the network byte order
 *   mask - [out] a netmask in the network byte order
 *   buf - [out] pointer to a buffer to hold result
 *   size - [in] buffer size
 *
 * RETURNS:
 *   Length of the resulting string on success, (xp_size_t)-1 on failure.
 *
 * DESCRIPTION:
 *   The netmask is converted to a prefix-length and appened to the resulting
 *   string following an ip address part and a slash. If it cannot be converted
 *   to a prefix-length, (xp_size_t)-1 is returned.
 *
 * SEE ALSO:
 *   <xp_inet4_ipnmtostrx>
 */
xp_size_t xp_inet4_ipnmtostrpx (
	xp_uint32_t ip, xp_uint32_t mask, xp_char_t* buf, xp_size_t size);

/*
int xp_inet_resolve (
	const xp_char_t* host, const xp_char_t* service,
	xp_port_t* port, xp_ip_t* ip);
*/

#ifdef __cplusplus
}
#endif

#endif
